﻿#include "CheckDelegate.h"

CheckDelegate::CheckDelegate(QObject* parent)
	:QStyledItemDelegate(parent)
{

}

void CheckDelegate::setCheckCount(size_t count)
{
	m_checkcount = count;
}

size_t CheckDelegate::CheckCount()const
{
	return m_checkcount;
}

/*
	根据数据模型中的状态绘制一个带有复选框的单元格，如果数据模型中的状态为选中，则绘制一个选中的复选框，否则绘制一个未选中的复选框
*/
void CheckDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
	/*
		函数接受	一个QPainter对象用于绘制，
				一个QStyleOptionViewItem对象用于描述要绘制的项的外观和元数据，
				以及一个QModelIndex对象用于引用要绘制的数据模型的特定项
	*/

	//判断是否被选中：
	bool isChecked = index.data(Qt::UserRole).toBool();

	QStyleOptionButton checkBoxStyle;			//用于描述按钮的外观和状态
	QCheckBox cbx;								//一个用于显示复选框的控件
	//将QCheckBox的外观和状态初始化到QStyleOptionButton中:
	checkBoxStyle.initFrom(&cbx);

	checkBoxStyle.rect = option.rect;			//确保绘制的复选框位于正确的位置

	//点击状况：
	checkBoxStyle.state = isChecked ? QStyle::State_On : QStyle::State_Off;
	//设置按钮为可选中状态：
	checkBoxStyle.state |= QStyle::State_Enabled;


	QApplication::style()	/*获取当前应用程序的样式*/
						->drawPrimitive(QStyle::PE_IndicatorCheckBox, &checkBoxStyle, painter)	/*绘制复选框*/;
}

/*
	处理用户与单元格的交互操作，当用户点击单元格时，更新数据模型中的状态，更新计数器，发送信号通知状态的改变，然后调用基类的方法完成剩余的处理工作
*/
bool CheckDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index)
{
	/*
		函数接受	一个QEvent对象用于描述事件，
				一个QAbstractItemModel对象用于引用数据模型，
				一个QStyleOptionViewItem对象用于描述要绘制的项的外观和元数据，
				以及一个QModelIndex对象用于引用要处理的数据模型的特定项
	*/

	//qDebug() << __FUNCTION__;


	//下行转换：
	auto ev = dynamic_cast<QMouseEvent*>(event);
	//如果事件是鼠标按下并且点击的区域是在该选项的区域下：
	if (event->type() == QEvent::MouseButtonPress && option.rect.contains(ev->position().toPoint()))
	{
		//获取当前项的状态：
		bool state = index.data(Qt::UserRole).toBool();
		//设置状态：
		model->setData(index, !state	/*当前状态的反状态*/, Qt::UserRole);		//将当前状态的反状态存储回Qt::UserRole角色中

		//此时是设置完模型的数据之后；因为是复选框，点击复选框一次，状态就要改变（选中和非选中），这里是统计更新完状态后	统计被选中的item的数量：（这样写好理解一些）
		if (!state)
				m_checkcount++;
		else
				m_checkcount--;


		//qDebug() << CheckCount();


		//发送信号：
		emit stateChanged(!state, index);
	}


	//调用基类的editorEvent()方法，让基类完成剩余的编辑事件处理工作:
	return QStyledItemDelegate::editorEvent(event, model, option, index);
}